home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 October: Mac OS SDK / Dev.CD Oct 00 SDK1.toast / Development Kits / Cross Platform / QuickTime 4.1.2 Windows SDK / ComponentIncludes / ComponentDispatchHelper.c next >
Encoding:
Text File  |  2000-04-12  |  14.6 KB  |  430 lines  |  [TEXT/R*ch]

  1. /*
  2.     File:        ComponentDispatchHelper.c
  3.  
  4.     Copyright:    © 1995-1997 by Apple Computer, Inc., all rights reserved.
  5.  
  6. */
  7.  
  8. // **** BEGIN: Error Checking the Required Macros
  9.  
  10. // Make sure BASENAME is defined
  11. #ifndef COMPONENT_BASENAME
  12.     #ifdef CALLCOMPONENT_BASENAME
  13.         #define COMPONENT_BASENAME()     CALLCOMPONENT_BASENAME()
  14.     #else
  15.         #error "COMPONENT_BASENAME or CALLCOMPONENT_BASENAME must be defined for ComponentDispatchHelper.c"
  16.     #endif
  17. #endif
  18.  
  19. // Make sure GLOBALS is defined
  20. #ifndef COMPONENT_GLOBALS
  21.     #ifdef CALLCOMPONENT_GLOBALS
  22.         #define COMPONENT_GLOBALS()     CALLCOMPONENT_GLOBALS()
  23.     #else
  24.         #error "COMPONENT_GLOBALS or CALLCOMPONENT_GLOBALS must be defined for ComponentDispatchHelper.c"
  25.     #endif
  26. #endif
  27.  
  28. // Make sure DISPATCH_FILE is defined
  29. #ifndef COMPONENT_DISPATCH_FILE
  30.     #error "COMPONENT_DISPATCH_FILE must be defined for ComponentDispatchHelper.c"
  31. #endif
  32.  
  33.  
  34. // Make sure UPP_PREFIX and SELECT_PREFIX are defined
  35. #if !defined(COMPONENT_UPP_SELECT_ROOT)  && !defined(COMPONENT_UPP_PREFIX) && !defined(COMPONENT_SELECT_PREFIX)
  36.     #error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
  37. #endif
  38. #ifdef COMPONENT_UPP_SELECT_ROOT
  39.     #if defined(COMPONENT_UPP_PREFIX) || defined(COMPONENT_SELECT_PREFIX)
  40.         #error "use only COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) for ComponentDispatchHelper.c"
  41.     #endif
  42. #else
  43.     #if !defined(COMPONENT_UPP_PREFIX) || !defined(COMPONENT_SELECT_PREFIX)
  44.         #error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
  45.     #endif
  46. #endif
  47. #ifndef COMPONENT_UPP_PREFIX
  48.     #ifndef COMPONENT_UPP_SELECT_ROOT
  49.         #error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
  50.     #else 
  51.         #define COMPONENT_UPP_PREFIX()        cdh_GLUE2(upp,COMPONENT_UPP_SELECT_ROOT())
  52.     #endif
  53. #endif
  54. #ifndef COMPONENT_SELECT_PREFIX
  55.     #ifndef COMPONENT_UPP_SELECT_ROOT
  56.         #error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
  57.     #else 
  58.         #define COMPONENT_SELECT_PREFIX()    cdh_GLUE2(k,COMPONENT_UPP_SELECT_ROOT())
  59.     #endif
  60. #endif
  61.     
  62. // Make sure SUBTYPE UPP_PREFIX and SELECT_PREFIX are defined correctly if they are used at all
  63. #if defined(COMPONENT_SUBTYPE_UPP_SELECT_ROOT) || defined(COMPONENT_SUBTYPE_UPP_PREFIX) || defined(COMPONENT_SUBTYPE_SELECT_PREFIX)
  64.     #ifdef COMPONENT_SUBTYPE_UPP_SELECT_ROOT
  65.         #if defined(COMPONENT_SUBTYPE_UPP_PREFIX) || defined(COMPONENT_SUBTYPE_SELECT_PREFIX)
  66.             #error "use only COMPONENT_SUBTYPE_UPP_PREFIX and COMPONENT_SUBTYPE_SELECT_PREFIX OR COMPONENT_SUBTYPE_UPP_SELECT_ROOT for ComponentDispatchHelper.c"
  67.         #endif
  68.     #else
  69.         #if !defined(COMPONENT_SUBTYPE_UPP_PREFIX) || !defined(COMPONENT_SUBTYPE_SELECT_PREFIX)
  70.             #error "COMPONENT_SUBTYPE_UPP_PREFIX and COMPONENT_SUBTYPE_SELECT_PREFIX OR COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c"
  71.         #endif
  72.     #endif
  73.     #ifndef COMPONENT_SUBTYPE_UPP_PREFIX
  74.         #ifndef COMPONENT_SUBTYPE_UPP_SELECT_ROOT
  75.             #error "COMPONENT_SUBTYPE_UPP_PREFIX or COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c"
  76.         #else 
  77.             #define COMPONENT_SUBTYPE_UPP_PREFIX()        cdh_GLUE2(upp,COMPONENT_SUBTYPE_UPP_SELECT_ROOT())
  78.         #endif
  79.     #endif
  80.     #ifndef COMPONENT_SUBTYPE_SELECT_PREFIX
  81.         #ifndef COMPONENT_SUBTYPE_UPP_SELECT_ROOT
  82.             #error "COMPONENT_SUBTYPE_SELECT_PREFIX or COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c"
  83.         #else 
  84.             #define COMPONENT_SUBTYPE_SELECT_PREFIX()    cdh_GLUE2(k,COMPONENT_SUBTYPE_UPP_SELECT_ROOT())
  85.         #endif
  86.     #endif
  87. #endif
  88.  
  89. // **** END: Error Checking the Required Macros
  90.  
  91.  
  92. #if TARGET_OS_MAC
  93.     #define PASCAL_RTN    pascal
  94. #else
  95.     #define PASCAL_RTN
  96. #endif
  97. #if !TARGET_OS_MAC || TARGET_CPU_PPC
  98.     #define C_DISPATCH_WITH_GLOBALS    1
  99.     #define C_DISPATCH_WITH_SWITCH    0
  100. #elif TARGET_CPU_68K
  101.     #ifdef COMPONENT_C_DISPATCHER
  102.         #define C_DISPATCH_WITH_GLOBALS    0
  103.         #define C_DISPATCH_WITH_SWITCH    1
  104.     #else
  105.         #define C_DISPATCH_WITH_GLOBALS    0
  106.         #define C_DISPATCH_WITH_SWITCH    0
  107.     #endif
  108. #else
  109.     #error "I have no idea what kind of machine you are using"
  110. #endif
  111.  
  112. /*
  113.     C_DISPATCH_WITH_GLOBALS implies global storage for dispatch information 
  114.                             and procinfos returned by COMPONENTSELECTORLOOKUP
  115.     C_DISPATCH_WITH_SWITCH  implies no global storage, dispatch by switch
  116.                             and no procinfos returned by COMPONENTSELECTORLOOKUP
  117. */
  118.  
  119.     #define COMPONENTSELECTORLOOKUP ADD_BASENAME(FindRoutineUPP)
  120.  
  121. #ifdef COMPONENT_DISPATCH_MAIN
  122.     #define COMPONENT_DISPATCH_ENTRY main
  123. #else
  124.     #define COMPONENT_DISPATCH_ENTRY ADD_BASENAME(ComponentDispatch)
  125. #endif
  126.  
  127. #ifndef __COMPONENTS_K__
  128.     #include "Components.k.h"
  129. #endif
  130.  
  131. #define    kCOMPONENT_NOERROR    ((ComponentFunctionUPP)-2)
  132. #define    kCOMPONENT_ERROR    ((ComponentFunctionUPP)-1)
  133. #define    kCOMPONENT_DELEGATE    ((ComponentFunctionUPP)0)
  134.  
  135. #ifndef cdh_GLUE
  136.     #define cdh_GLUE(a,b)        a##b
  137. #endif
  138. #ifndef cdh_GLUE2
  139.     #define cdh_GLUE2(a,b)        cdh_GLUE(a,b)
  140. #endif
  141. #ifndef cdh_GLUE3
  142.     #define cdh_GLUE3(a,b,c)    cdh_GLUE2(cdh_GLUE2(a,b),c)
  143. #endif
  144.  
  145. #if TARGET_RT_LITTLE_ENDIAN
  146.     #define ComponentCallLittleEndian         ComponentCall
  147. #else
  148.     #define ComponentCallLittleEndian         ComponentDelegate
  149. #endif
  150.  
  151. #ifdef forPublicQTiRelease
  152.     #define ComponentQTiCall(procName)                ComponentCall(procName)
  153.     #define QTIComponentCall(procName)                ComponentCall(procName)
  154. #endif
  155.  
  156. #define ADD_BASENAME(name) cdh_GLUE2(COMPONENT_BASENAME(),name)
  157.  
  158. #if C_DISPATCH_WITH_GLOBALS
  159.     PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params, COMPONENT_GLOBALS());
  160.     static ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num, ProcInfoType *procInfo);
  161.  
  162.     #if TARGET_OS_MAC && TARGET_CPU_PPC
  163.         // entry point for PowerPC native components
  164.         struct RoutineDescriptor ADD_BASENAME(ComponentDispatchRD) =
  165.           BUILD_ROUTINE_DESCRIPTOR((kPascalStackBased | RESULT_SIZE (kFourByteCode) |
  166.                                     STACK_ROUTINE_PARAMETER (1, kFourByteCode) |
  167.                                     STACK_ROUTINE_PARAMETER (2, kFourByteCode)),COMPONENT_DISPATCH_ENTRY);
  168.     #endif
  169.     
  170.     PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params,COMPONENT_GLOBALS())
  171.     {
  172.         ComponentFunctionUPP theProc;
  173.         ComponentResult result = badComponentSelector;
  174.         ProcInfoType theProcInfo;
  175.         
  176.         theProc = COMPONENTSELECTORLOOKUP(params->what, &theProcInfo);
  177.  
  178.         if (theProc) {
  179.             if ( (theProc != kCOMPONENT_ERROR) && (theProc != kCOMPONENT_NOERROR) ) {
  180.                 if (theProcInfo != 0) {
  181. #if TARGET_API_MAC_CARBON
  182. // temporary workaround for CallComponentFunctionWithStorageProcInfo failing on MacOS X:
  183. // build a temporary UPP and then throw it away afterwards.
  184.                     ComponentFunctionUPP tempUPP = NewComponentFunctionUPP( (ProcPtr)theProc, theProcInfo );
  185.                     result = CallComponentFunctionWithStorage((Handle) storage, params, tempUPP);
  186.                     DisposeComponentFunctionUPP( tempUPP );
  187. #else
  188.                     result = CallComponentFunctionWithStorageProcInfo((Handle) storage, params, (ProcPtr)theProc, theProcInfo);
  189. #endif
  190.                 }
  191.             }
  192.             else if ( theProc == kCOMPONENT_NOERROR ) {
  193.                 result = noErr;
  194.             }
  195.         }
  196.     #ifdef GET_DELEGATE_COMPONENT
  197.         else
  198.             return DelegateComponentCall(params, GET_DELEGATE_COMPONENT());
  199.     #endif
  200.         return result;
  201.     }
  202. #elif C_DISPATCH_WITH_SWITCH
  203.     PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params, COMPONENT_GLOBALS());
  204.     static ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num);
  205.  
  206.     PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY( ComponentParameters *params, COMPONENT_GLOBALS() )
  207.         {
  208.         ComponentFunctionUPP theProc;
  209.         
  210.         ComponentResult result = badComponentSelector;
  211.         theProc = COMPONENTSELECTORLOOKUP(params->what);
  212.  
  213.         if (theProc) {
  214.             if ( (theProc != kCOMPONENT_ERROR) && (theProc != kCOMPONENT_NOERROR) ) {
  215.                 result = CallComponentFunctionWithStorage((Handle) storage, params, theProc);
  216.             }
  217.             else if ( theProc == kCOMPONENT_NOERROR ) {
  218.                 result = noErr;
  219.             }
  220.         }
  221.     #ifdef GET_DELEGATE_COMPONENT
  222.         else
  223.             result = DelegateComponentCall(params, GET_DELEGATE_COMPONENT());
  224.     #endif
  225.         return result;
  226.         }
  227. #endif
  228.  
  229. #if C_DISPATCH_WITH_GLOBALS
  230.     typedef struct {
  231.         ComponentFunctionUPP    theProc;
  232.         ProcInfoType            theProcInfo;
  233.     } cdhDispatchInfoRecord;
  234.     
  235.     typedef struct {
  236.         short                    rangeMax;
  237.         cdhDispatchInfoRecord    *cdhDispatchInfoP;
  238.     } cdhRangeDispatchInfoRecord;
  239.     
  240.     #define ComponentSelectorOffset(theOffset)    enum {SelOffset = theOffset};
  241.     
  242.     #define ComponentRangeCount(theCount)        enum {RangeCount = theCount};
  243.     #define ComponentRangeShift(theShift)        enum {RangeShift = theShift};
  244.     #define ComponentRangeMask(theMask)            enum {RangeMask = cdh_GLUE2(0x,theMask)};
  245.     
  246.     #define ComponentStorageType(theType)
  247.     #define ComponentDelegateByteOffset(theOffset)
  248.  
  249.  
  250.     #define StdComponentCall(procName)    \
  251.         (ComponentFunctionUPP)ADD_BASENAME(procName), cdh_GLUE3(uppCallComponent,procName,ProcInfo),
  252.     
  253.     #define ComponentCall(procName)    \
  254.         (ComponentFunctionUPP)ADD_BASENAME(procName), cdh_GLUE3(COMPONENT_UPP_PREFIX(),procName,ProcInfo),
  255.  
  256.     #define ComponentSubTypeCall(procName)    \
  257.         (ComponentFunctionUPP)ADD_BASENAME(procName), cdh_GLUE3(COMPONENT_SUBTYPE_UPP_PREFIX(),procName,ProcInfo),
  258.  
  259.     #define ComponentError(procName)            kCOMPONENT_ERROR, 0,
  260.     
  261.     #define StdComponentNoError(procName)         kCOMPONENT_NOERROR, 0,
  262.     #define ComponentNoError(procName)            kCOMPONENT_NOERROR, 0,
  263.     #define ComponentSubTypeNoError(procName)     kCOMPONENT_NOERROR, 0,
  264.     
  265.     #define ComponentDelegate(procName)            kCOMPONENT_DELEGATE, 0,
  266.     
  267.     
  268.     #define ComponentRangeUnused(rangeNum) \
  269.         static cdhDispatchInfoRecord cdh_GLUE2(cdhDispatchInfo,rangeNum)[1] = { 0 };    \
  270.         enum {cdh_GLUE2(cdhDispatchMax,rangeNum) = 0};
  271.         
  272.     #define ComponentRangeBegin(rangeNum)    \
  273.         static cdhDispatchInfoRecord cdh_GLUE2(cdhDispatchInfo,rangeNum)[] = {
  274.         
  275.     #define ComponentRangeEnd(rangeNum)                \
  276.         };        \
  277.         enum {cdh_GLUE2(cdhDispatchMax,rangeNum) = sizeof(cdh_GLUE2(cdhDispatchInfo,rangeNum)) / sizeof(cdhDispatchInfoRecord)};
  278.     
  279.     #define ComponentComment(theComment)
  280.  
  281.     // define the static dispatch tables
  282.     #include COMPONENT_DISPATCH_FILE
  283.     
  284.     #undef ComponentSelectorOffset
  285.     #undef ComponentRangeCount
  286.     #undef ComponentRangeShift
  287.     #undef ComponentRangeMask
  288.     #undef StdComponentCall
  289.     #undef ComponentCall
  290.     #undef ComponentSubTypeCall
  291.     #undef ComponentError
  292.     #undef StdComponentNoError
  293.     #undef ComponentNoError
  294.     #undef ComponentSubTypeNoError
  295.     #undef ComponentDelegate
  296.     #undef ComponentRangeUnused
  297.     #undef ComponentRangeBegin
  298.     #undef ComponentRangeEnd    
  299.     
  300.     #define ComponentSelectorOffset(theOffset)
  301.     #define ComponentRangeCount(theCount)
  302.     #define ComponentRangeShift(theShift)
  303.     #define ComponentRangeMask(theMask)
  304.     #define StdComponentCall(procName)
  305.     #define ComponentCall(procName)
  306.     #define ComponentSubTypeCall(procName)
  307.     #define ComponentError(procName)
  308.     #define StdComponentNoError(procName)
  309.     #define ComponentNoError(procName)
  310.     #define ComponentSubTypeNoError(procName)
  311.     #define ComponentDelegate(procName)
  312.     
  313.     #define ComponentRangeUnused(rangeNum) \
  314.         { 0, nil },
  315.     #define ComponentRangeBegin(rangeNum)        \
  316.         { cdh_GLUE2(cdhDispatchMax,rangeNum), cdh_GLUE2(cdhDispatchInfo,rangeNum) },
  317.     #define ComponentRangeEnd(rangeNum)
  318.     
  319.     // define the static range tables (max per range and point to dispatch tables)
  320.     static cdhRangeDispatchInfoRecord cdhRangeDispatch[RangeCount+1] = {
  321.         #include COMPONENT_DISPATCH_FILE
  322.     };
  323.     
  324.     ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num, ProcInfoType *procInfo)
  325.     {
  326.         ProcInfoType pinfo = 0;
  327.         ComponentFunctionUPP result = kCOMPONENT_DELEGATE;
  328.         cdhDispatchInfoRecord *infoP = nil;
  329.         short theRange;
  330.         
  331.         theRange = selector_num >> RangeShift;
  332.         if (theRange < 0) {
  333.             selector_num += SelOffset;
  334.             if (selector_num >= 0) {
  335.                 infoP = &(cdhRangeDispatch[0].cdhDispatchInfoP)[selector_num];
  336.             }
  337.         } else {
  338.             if (theRange < RangeCount) {
  339.                 selector_num &= RangeMask;
  340.                 if (selector_num < cdhRangeDispatch[theRange+1].rangeMax)
  341.                     infoP = &(cdhRangeDispatch[theRange+1].cdhDispatchInfoP)[selector_num];
  342.             }
  343.         }
  344.         
  345.         if (infoP) {
  346.             *procInfo = infoP->theProcInfo;
  347.             result = infoP->theProc;
  348.         } 
  349.         return result;
  350.     }
  351.  
  352. #elif C_DISPATCH_WITH_SWITCH
  353.     ComponentFunctionUPP COMPONENTSELECTORLOOKUP( short selector_num )
  354.     {
  355.         ComponentFunctionUPP aProc = (ComponentFunctionUPP) kCOMPONENT_DELEGATE;
  356.     
  357.         #define ComponentSelectorOffset(theOffset)
  358.  
  359.         #define    case_ComponentCall(kPrefix,procName)    case cdh_GLUE3(kPrefix,procName,Select): aProc = (ComponentFunctionUPP)ADD_BASENAME(procName); break;
  360.         #define StdComponentCall(procName)                case_ComponentCall(kComponent,procName)
  361.         #define ComponentCall(procName)                    case_ComponentCall(COMPONENT_SELECT_PREFIX(),procName)
  362.         #define ComponentSubTypeCall(procName)            case_ComponentCall(COMPONENT_SUBTYPE_SELECT_PREFIX(),procName)
  363.  
  364.         #define    case_ComponentNoError(kPrefix,procName)    case cdh_GLUE3(kPrefix,procName,Select): aProc = (ComponentFunctionUPP)kCOMPONENT_NOERROR; break;
  365.         #define StdComponentNoError(procName)            case_ComponentNoError(kComponent,procName)
  366.         #define ComponentNoError(procName)                case_ComponentNoError(COMPONENT_SELECT_PREFIX(),procName)
  367.         #define ComponentSubTypeNoError(procName)        case_ComponentNoError(COMPONENT_SUBTYPE_SELECT_PREFIX(),procName)
  368.  
  369.         #define ComponentError(procName)                //ComponentError for C_DISPATCH_WITH_SWITCH uses default case (delegate if we can)
  370.  
  371.         #define ComponentDelegate(procName)                //The default case for C_DISPATCH_WITH_SWITCH is to delegate if we can, error if we can't
  372.         
  373.         #define ComponentRangeCount(theCount)
  374.         #define ComponentRangeShift(theShift)
  375.         #define ComponentRangeMask(theMask)
  376.         #define ComponentRangeBegin(rangeNum)
  377.         #define ComponentRangeEnd(rangeNum)
  378.         #define ComponentRangeUnused(rangeNum)
  379.         #define ComponentStorageType(theType)
  380.         #define ComponentDelegateByteOffset(theOffset)
  381.         #define ComponentComment(theComment)
  382.  
  383.         switch (selector_num) {
  384.             #include COMPONENT_DISPATCH_FILE
  385.             }
  386.     
  387.         return aProc;
  388.     }
  389. #endif
  390.  
  391. #ifdef OVERRIDE_CANDO
  392.     ComponentResult OVERRIDE_CANDO( COMPONENT_GLOBALS(), short ftnNumber, ComponentResult result);
  393. #endif
  394.  
  395. PASCAL_RTN ComponentResult ADD_BASENAME(CanDo)( COMPONENT_GLOBALS(), short ftnNumber );
  396. PASCAL_RTN ComponentResult ADD_BASENAME(CanDo)( COMPONENT_GLOBALS(), short ftnNumber )
  397. {
  398.     ComponentResult    result;
  399. #if C_DISPATCH_WITH_GLOBALS
  400.     ProcInfoType ignore;
  401.     result = (ComponentResult) COMPONENTSELECTORLOOKUP(ftnNumber, &ignore);
  402. #else
  403.     result = (ComponentResult) COMPONENTSELECTORLOOKUP(ftnNumber);
  404. #endif
  405.     
  406.     /* check for a ComponentError */
  407.     if ( result == (ComponentResult) kCOMPONENT_ERROR )
  408.         result = false;
  409.     else if ( result == (ComponentResult) kCOMPONENT_DELEGATE )
  410.         result = false;
  411.     else
  412.         result = true;
  413.  
  414. #ifdef GET_DELEGATE_COMPONENT
  415.     /* if we're delegated, then keep looking */
  416.     if (!result)
  417.         {
  418.         if (GET_DELEGATE_COMPONENT())
  419.             result = CallComponentCanDo( GET_DELEGATE_COMPONENT(), ftnNumber );
  420.         }
  421. #endif
  422.  
  423. #ifdef OVERRIDE_CANDO
  424.     result = OVERRIDE_CANDO( storage, ftnNumber, result);
  425. #endif
  426.  
  427.     return result;
  428. }
  429.  
  430.